import re
from django.contrib.auth import login
from django.shortcuts import render, redirect
from django import http
# 拼接url字符串
# https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=101518219&redirect_uri=http://www.meiduo.site:8000/oauth_callback&state=test
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.carts.utils import merge_cookie_to_redis
from apps.oauth.constants import OPENID_TOKEN_EXPRIES_TIME
from apps.oauth.models import OAuthQQUser
from apps.oauth.utils import get_token_openid, check_openid_token
from apps.users.models import User
from meiduo_mall import settings
from utils.response_code import RETCODE
from QQLoginTool.QQtool import OAuthQQ
import logging
logger = logging.getLogger('django')


class OauthQQURLView(View):
    def get(self,request):
        state = request.GET.get('next')
        # 创建qq实例对象
        qq = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            redirect_uri = settings.QQ_REDIRECT_URI,
            client_secret=settings.QQ_CLIENT_SECRET,
            state=state
        )
        login_url = qq.get_qq_url()
        # login_url = 'https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=101518219&redirect_uri=http://www.meiduo.site:8000/oauth_callback&state=test'

        return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok','login_url':login_url})

    """
    对于应用而言，需要进行两步：
1. 获取Authorization Code；     用户登录获取code
2. 通过Authorization Code获取Access Token
    """

class OauthQQUserView(View):
    def get(self,request):
        """
        1.获取code(用户同意登录后，腾讯返回给我们)
        2.通过code获取token(我们需要把获取的code和创建应用的serect一并给qq服务器，qq服务器会认证
        认证没有问题会返回给我们token)
        3.根据token获取openid
        4.判断openid对应的user信息是否存在，如果不存在则进行绑定，存在则进行跳转
        """
        # 1.获取code
        code = request.GET.get('code')
        if code is None:
            return http.HttpResponseBadRequest('参数不齐')

        # 2.通过code获取token
        # 创建qq实例
        qq = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            redirect_uri=settings.QQ_REDIRECT_URI,
            client_secret=settings.QQ_CLIENT_SECRET
        )
        token = qq.get_access_token(code)

        #　3.获取openid
        openid = qq.get_open_id(token)

        # 4.判断openid对应的user信息是否存在，如果不存在则进行绑定，存在则进行跳转
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            openid_token = get_token_openid(openid)
            return render(request,'oauth_callback.html',context={'openid':openid_token})

        else:
            user = qquser.user
            login(request,user)
            next = request.GET.get('state')
            if next:
                response = redirect(next)
            else:
                response = redirect(reverse("contents:index"))
            response.set_cookie('username',user.username,max_age=14*24*3600)
            response = merge_cookie_to_redis(request=request, user=user, response=response)
            return response
        return render(request,'oauth_callback.html')


    def post(self,request):
        data = request.POST
        # 接受数据
        mobile = data.get('mobile')
        password = data.get('password')
        sms_code_client = data.get('sms_code')
        access_token = data.get('access_token')
        # 验证数据
        if not all([mobile,password,sms_code_client,access_token]):
            return http.HttpResponseBadRequest("缺少必传参数！")
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return http.HttpResponseBadRequest("请输入正确的手机号！")
        if not re.match(r'^[a-zA-Z0-9\.,_-]{8,20}$',password):
            return http.HttpResponseBadRequest("请输入8-20为密码！")
        # 连接数据库
        redis_conn = get_redis_connection('code')
        # 获取数据库中的短信验证码
        sms_code_server = redis_conn.get("sms_%s"%mobile)
        # 验证短信验证码是否过期
        if not sms_code_server:
            return http.HttpResponseBadRequest('短信验证码已过期!')
        if sms_code_client != sms_code_server.decode():
            return http.HttpResponseBadRequest('短信验证码错误!')
        logger.info(sms_code_server)
        openid = check_openid_token(access_token)
        if openid is None:
            return http.HttpResponseBadRequest('openid错误')

        # user 需要用手机号进行判断　如果手机号已注册，user信息已存在，如果手机号没注册，创建一个user
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else:
            if not user.check_password(password):
                return http.HttpResponseBadRequest('密码错误')
        try:
            OAuthQQUser.objects.create(
                openid=openid,
                user=user
            )
        except Exception as e:
            logger.error(e)
            return http.HttpResponseBadRequest('数据库错误！')
        # 保持登录状态
        login(request,user)

        # 设置cookie
        next = request.GET.get('state')
        if next:
            response = redirect(next)
        else:
            response = redirect(reverse("contents:index"))

        response.set_cookie('username',user.username,max_age=14*24*3600)

        return response






# itsdangerous加密
# from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
# from meiduo_mall import settings
# # 1.创建实例对象
# s = Serializer(settings.SECRET_KEY,300)
# data = {'openid':'abcdef'}
# token = s.dumps(data)
# xxx.xxx.xx
# b'eyJhbGciOiJIUzUxMiIsImV4cCI6MTU1NzgzNTk3MiwiaWF0IjoxNTU3ODM1NjcyfQ.eyJvcGVuaWQiOiJhYmNkZWYifQ.JhaioC46TMyz0y_fYRcdtDmnH9TFLLggm_64fSMixwyfeWD4WvxV8KIFh7P7LbQEJBI4xpR7ZPkEryI2TX3_7A'
# token.decode()
# 'eyJhbGciOiJIUzUxMiIsImV4cCI6MTU1NzgzNjAwNiwiaWF0IjoxNTU3ODM1NzA2fQ.eyJvcGVuaWQiOiJhYmNkZWYifQ.u9aVgqZCl9ACssT3DDaTW27l2mzgS37vmMQQrpHDyM3P6W69aZ3IJ3sQka_hQVjhCQ5z4Py6CvjgMMidLxTUOQ'

# itsdangerous解密
# from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
# from meiduo_mall import settings
#
# s = Serializer(settings.SECRET_KEY,OPENID_TOKEN_EXPRIES_TIME)
# s.loads(token)
# {'openid': 'abcdef'}
